using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UIElements;

public interface IBagSystem
{
    List<BagItemData> dataList { get; }
    List<IBagItemView> viewList { get; }

    IBagItemView selectedView { set; get; }

    IEnumerator BagSelectedPerformer(BagSelectedGA bagSelectedGA);
}

public class StoreSystem : Singleton<StoreSystem>, IBagSystem
{
    void OnEnable()
    {
        ActionSystem.AttachPerformer<BagSelectedGA>(BagSelectedPerformer);
    }

    void OnDisable()
    {
        ActionSystem.DetachPerformer<BagSelectedGA>();
    }

    IEnumerator BagSelectedPerformer(BagSelectedGA bagSelectedGA)
    {
        if (viewList.Contains(bagSelectedGA.View))
        {
            foreach (var view in viewList)
            {
                view.IsHighlighted = false;
            }
            bagSelectedGA.View.IsHighlighted = true;
            selectedView = bagSelectedGA.View;
            yield return null;
        }
    }

    public List<BagItemData> dataList { get; private set; } = new List<BagItemData>();
    public List<IBagItemView> viewList { get; private set; } = new List<IBagItemView>();
    public IBagItemView selectedView { get; set; }

    public static readonly Dictionary<string, List<string>> ComposeDict = new Dictionary<string, List<string>>
    {
        { "腐败大剑", new List<string> { "朔击之枪", "鲜血之镰" } },
    };

    public static readonly Dictionary<string, int> ItemTotalPriceDict = new Dictionary<string, int>
    {
        { "朔击之枪", 600 },
        { "鲜血之镰", 600 },
        { "腐败大剑", 2100 },
    };
    internal static object showTitle;

    [SerializeField] private Bag Prefab;
    [SerializeField] private RelicBoardView relicBoardViewPrefab;
    [SerializeField] private GoldView goldViewPrefab;
    [SerializeField] private GameObject Slot;
    [SerializeField] private GameObject relicBoardViewSlot;
    [SerializeField] private GameObject goldViewSlot;
    private Bag bag;
    private RelicBoardView relicBoardView;
    private GoldView goldView;

    public void Setup()
    {
        if (Prefab == null || Slot == null)
        {
            Debug.LogError("storePrefab 或 StoreViewSlot 未设置！");
            return;
        }

        bag = Instantiate(Prefab, Slot.transform);

        List<BagItemData> juniorRelics = new List<BagItemData>
        {
            new XXZL(), new XXZL(), new SJZQ(), new XXZL(), new XXZL(),
            new XXZL(), new SJZQ(), new SJZQ(), new SJZQ(), new SJZQ(),
        };
        List<BagItemData> highRelics = new List<BagItemData> { new FBDJ(), new FBDJ() };

        List<List<BagItemData>> relicsAsBase = new List<List<BagItemData>> { juniorRelics, highRelics };

        bag.Setup(relicsAsBase);

        viewList = bag.GetViews();

        foreach (var view in viewList)
        {
            if (view is MonoBehaviour mb)
            {
                var text = mb.GetComponent<RelicViewExText>();
                if (text != null)
                    text.SetupText(showTitle: true, showPrice: true);
            }
        }

        SetupRelicBoardView();
        goldView = Instantiate(goldViewPrefab, goldViewSlot.transform);
    }

    public void SetupRelicBoardView()
    {
        relicBoardView = Instantiate(relicBoardViewPrefab, relicBoardViewSlot.transform);
        relicBoardView.Setup(InfoSystem.Instance.hero.Relics);
    }

    public void Close()
    {
        InfoSystem.Instance.hero.Relics = relicBoardView.relics;
        InfoSystem.Instance.SaveGame();

        Destroy(bag.gameObject);
        Destroy(relicBoardView.gameObject);
        Destroy(goldView.gameObject);
    }

    // =======================
    // 购买主逻辑
    // =======================
    public void Buy()
    {
        if (!(selectedView is RelicView relicView))
        {
            Debug.LogWarning("没有选中装备！");
            return;
        }

        Relic target = relicView.relic;
        int price = CalculatePrice(relicBoardView.relics, target.ShowTitle);
        if (goldView.GoldNumber < price)
        {
            Debug.Log($"金币不足，需要 {price}，当前 {goldView.GoldNumber}");
            return;
        }

        goldView.GoldNumber -= price;

        // 修复：先消耗子材料，排除目标本身
        ConsumeSubRelics(relicBoardView.relics, target.ShowTitle, target);

        relicBoardView.AddRelic(target);

        Debug.Log($"购买成功：{target.ShowTitle}，剩余金币：{goldView.GoldNumber}");
    }

    // =======================
    // 递归消耗子装备（修复版，排除目标本身）
    // =======================
    private void ConsumeSubRelics(List<Relic> owned, string title, Relic exclude)
    {
        if (!ComposeDict.TryGetValue(title, out var children)) return;

        foreach (var childTitle in children)
        {
            var relicToRemove = owned.Find(r => r.ShowTitle == childTitle && r != exclude);
            if (relicToRemove != null)
            {
                relicBoardView.RemoveRelic(relicToRemove);
                ConsumeSubRelics(owned, childTitle, exclude);
            }
            else
            {
                Debug.LogWarning($"购买时缺少材料：{childTitle}");
            }
        }
    }

    // =======================
    // 计算价格
    // =======================
    public int CalculatePrice(List<Relic> owned, string targetTitle)
    {
        var ownedCount = new Dictionary<string, int>();
        foreach (var r in owned)
        {
            if (ownedCount.ContainsKey(r.ShowTitle)) ownedCount[r.ShowTitle]++;
            else ownedCount[r.ShowTitle] = 1;
        }

        return CalculatePriceInternal(targetTitle, ownedCount, new HashSet<string>());
    }

    private int CalculatePriceInternal(string showTitle, Dictionary<string, int> ownedCount, HashSet<string> visiting)
    {
        if (visiting.Contains(showTitle))
        {
            Debug.LogWarning($"检测到合成循环，跳过：{showTitle}");
            return 0;
        }
        visiting.Add(showTitle);

        if (!ItemTotalPriceDict.ContainsKey(showTitle))
            throw new KeyNotFoundException($"物品 [{showTitle}] 在价格字典 ItemTotalPriceDict 中未配置价格！");

        int directPrice = ItemTotalPriceDict[showTitle];

        if (!ComposeDict.TryGetValue(showTitle, out var children))
        {
            visiting.Remove(showTitle);
            return directPrice;
        }

        int childrenValueSum = 0;
        foreach (var childTitle in children)
            childrenValueSum += CalculateSubItemValue(childTitle, ownedCount, new HashSet<string>(visiting));

        visiting.Remove(showTitle);
        return Math.Max(0, directPrice - childrenValueSum);
    }

    private int CalculateSubItemValue(string childTitle, Dictionary<string, int> ownedCount, HashSet<string> visiting)
    {
        if (visiting.Contains(childTitle))
        {
            Debug.LogWarning($"子件检测到合成循环，跳过：{childTitle}");
            return 0;
        }
        visiting.Add(childTitle);

        if (ownedCount.TryGetValue(childTitle, out int count) && count > 0)
        {
            ownedCount[childTitle]--;
            int subItemValue = ItemTotalPriceDict.TryGetValue(childTitle, out int value) ? value : 0;
            visiting.Remove(childTitle);
            return subItemValue;
        }

        visiting.Remove(childTitle);
        return 0;
    }

    IEnumerator IBagSystem.BagSelectedPerformer(BagSelectedGA bagSelectedGA)
    {
        return BagSelectedPerformer(bagSelectedGA);
    }
}
